﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;

namespace DroneLib.Communication
{
    public class SerialStream : MavStream
    {
        public string PortName { get; set; }
        public int BaudRate { get; set; } = 57600;

        public override bool Connected => _SP == null ? false : _SP.IsOpen;

        SerialPort _SP;


        public SerialStream()
        {

        }

        public SerialStream(string port,int baudRate)
        {
            PortName = port.ToUpper();
            BaudRate = baudRate;
        }

        public override long Length => _SP == null ? 0 : _SP.BytesToRead;

        public override void Close()
        {
            IsOpen = false;
            _SP?.Close();            
        }

        public override void Flush()
        {
            if (IsOpen == false)
                return;

            _SP.BaseStream.Flush();
        }

        public override void Open()
        {
            if(_SP!= null) 
            {
                if (_SP.IsOpen)
                    _SP.Close();
                _SP.Dispose();
                _SP = null;
            }

            if (SerialPort.GetPortNames().Contains(PortName) == false)
                return;

            _SP= new SerialPort(PortName,BaudRate);
            try
            {
                _SP.Open();
                IsOpen = true;
                RaiseLinkConnectedEvent(true);
            }
            catch(Exception ex)
            {
                ConnectionFailed = true;
                Error = ex.Message;
                RaiseLinkConnectedEvent(false);
                return;
            }
            StartMessageLoop();
            _Name = $"SERIAL://{PortName}:{BaudRate}".ToUpper();
        }

        public override void Reconnect()
        {
            Open();
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            if (_SP != null && _SP.IsOpen)
                try
                {
                    return _SP.Read(buffer, offset, count);
                }
                catch (Exception ex)
                {
                    Error = ex.Message;
                    return -1;
                }
            else
                return -1;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            if (IsOpen == false)
                return;

            try
            {
                _SP.Write(buffer, offset, count);
            }
            catch (Exception ex)
            {
                Error = ex.Message;
                //RaiseLinkBrokenEvent();
            }
        }
    }
}
